package edu.hawaii.myisern.action;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.net.MalformedURLException;
import javax.xml.bind.JAXBException;
import org.junit.Before;
import org.junit.Test;
import org.xml.sax.SAXException;
import com.meterware.httpunit.WebConversation;
import com.meterware.httpunit.WebForm;
import com.meterware.httpunit.WebRequest;
import com.meterware.httpunit.WebResponse;
import com.meterware.httpunit.WebTable;

/**
 * Test case for OrganizationActionBean.java
 * 
 * @author Shaoxuan Zhang
 *
 */
public class TestOrganizationActionBean {

  /** Get the test host. */
  //private String testHost = "http://localhost:8080/";
  private String testHost = "http://localhost:8080/";
  private WebConversation conversation = new WebConversation();
  private WebRequest organizationsRequest;
  private final String HEAD_FRAME = "navigation";
  private final String LIST_TABLE = "organizationsList";
  private final String VIEW_TABLE = "organizationView";
  private final String EDIT_TABLE = "organizationEdit";
  private final String MESSAGE_TABLE = "MessageTable";
  private final String VIEW_FORM = "viewOrganization";
  private final String EDIT_FORM = "editOrganization";
  /**
   * Constructor
   * @throws JAXBException when JAXB fails.
   * @throws SAXException when SAX fails.
   */
  public TestOrganizationActionBean() throws JAXBException, SAXException {
    //empty constructor
  }
  /**
   * Initialize a web conversation.
   * @throws MalformedURLException java.net.MalformedURLException
   * @throws IOException java.io.IOException
   * @throws SAXException thrown if there is an error parsing this response
   */
  @Before public void setUp() throws MalformedURLException, IOException, SAXException {
    // Get welcome.jsp page and check for successful retrieval
    String Url = testHost + "myisern";
    WebResponse response = conversation.getResponse(Url);
    assertEquals("See if get the right page", "Login", response.getTitle());
    //login
    WebForm form = response.getFormWithID("LoginForm");
    WebRequest request = form.getRequest();
    request.setParameter("username", "admin");
    request.setParameter("password", "admin");
    response = conversation.getResponse(request);
    assertEquals("Check if login succeeded.", 2,response.getFrameNames().length);
    response = response.getSubframeContents(HEAD_FRAME);
    this.organizationsRequest = response.getLinkWith("Organizations").getRequest();
  }
  
  /**
   * Test the Organizations list page.
   * @throws SAXException thrown if there is an error parsing this response
   * @throws IOException java.io.IOException
   */
  @Test public void testListOrganization() throws SAXException, IOException {
    WebResponse response = this.conversation.getResource(organizationsRequest);
    WebTable listTable = response.getTableWithID(LIST_TABLE);
    assertEquals("Checking list page title", "Organizations List", response.getTitle());
    assertTrue("Table should be something inside", listTable.getRowCount() > 10);
    assertEquals("The table should have 2 column", 3, listTable.getColumnCount());
    /*
    List<String> listName = new ArrayList<String>();
    for (int i = 1; i < listTable.getRowCount(); ++i) {
      String name = listTable.getCellAsText(i, 0);
      listName.add(name);
      assertTrue("Check if " + name + " is in the system", this.myIsern.hasOrganization(name));
    }
    for (Organization organization : this.myIsern.getOrganizationList()) {
      assertTrue("Check if " + organization.getName() + " is in the list", 
          listName.contains(organization.getName()));
    }
    */
  }

  /**
   * Test the Organizations View page.
   * Name in view page should be the same as it in the link.
   * @throws SAXException thrown if there is an error parsing this response
   * @throws IOException java.io.IOException
   */
  @Test public void testOrganizationView() throws SAXException, IOException {
    WebResponse response = this.conversation.getResource(organizationsRequest);
    WebTable listTable = response.getTableWithID(LIST_TABLE);
    String testName = listTable.getCellAsText(1, 0);
    WebRequest request = response.getLinkWith(testName).getRequest();
    response = this.conversation.getResource(request);
    assertEquals("Checking Organization View page", "View Organization", response.getTitle());
    WebTable viewTable = response.getTableWithID(VIEW_TABLE);
    assertEquals("Checking Name in viewTable", testName, viewTable.getCellAsText(0, 1));
  }
  
  /**
   * Test edit page. 
   * All information in view page should be in edit page too.
   * @throws SAXException thrown if there is an error parsing this response
   * @throws IOException java.io.IOException
   */
  @Test public void testOrganizationEdit() throws IOException, SAXException {
    //Go to list page
    WebResponse response = this.conversation.getResource(organizationsRequest);
    //Go to view page
    WebTable listTable = response.getTableWithID(LIST_TABLE);
    String testName = listTable.getCellAsText(1, 0);
    WebRequest request = response.getLinkWith(testName).getRequest();
    response = this.conversation.getResource(request);
    //Save viewTable for verification
    WebTable viewTable = response.getTableWithID(VIEW_TABLE);
    //Go to edit page
    WebForm viewForm = response.getFormWithID(VIEW_FORM);
    request = viewForm.getRequest("edit");
    request.setParameter("name", testName);
    response = this.conversation.getResource(request);
    assertEquals("Checking Organization Edit page", "Edit Organization", response.getTitle());
    WebTable editTable = response.getTableWithID(EDIT_TABLE);
    assertEquals("Checking Organization Edit page", 
        viewTable.getRowCount(), editTable.getRowCount());
    /*
    for (int i = 0; i < editTable.getRowCount(); ++i) {
      assertEquals("Checking " + editTable.getCellAsText(i, 0), 
          viewTable.getCellAsText(i, 1), editTable.getCellAsText(i, 1));
    }
    */
    WebForm editForm = response.getFormWithID(EDIT_FORM);
    request = editForm.getRequest("save");
    response = this.conversation.getResource(request);
    assertEquals("Checking list page title", "Organization Error", response.getTitle());
  }
  
  /**
   * Test New Organization.
   * @throws SAXException thrown if there is an error parsing this response
   * @throws IOException java.io.IOException
   */
  @Test public void testOrganizationNew() throws IOException, SAXException {
    //Go to list page
    WebResponse response = this.conversation.getResource(organizationsRequest);
    WebRequest request = response.getLinkWith("New").getRequest();
    response = this.conversation.getResource(request);
    WebTable editTable = response.getTableWithID(EDIT_TABLE);
    assertEquals("Checking edit page title", "Edit Organization", response.getTitle());
    assertEquals("Checking Name", "", editTable.getCellAsText(0, 1));
    WebForm editForm = response.getFormWithID(EDIT_FORM);
    request = editForm.getRequest("save");
    response = this.conversation.getResource(request);
    assertEquals("Checking list page title", "Organizations List", response.getTitle());
    WebTable messageTable = response.getTableWithID(MESSAGE_TABLE);
    assertEquals("Checking table message", "Nothing is added.", messageTable.getCellAsText(0, 0));
  }

  /**
   * Test Delete Organization.
   * @throws SAXException thrown if there is an error parsing this response
   * @throws IOException java.io.IOException
   */
  @Test public void testOrganizationDelete() throws SAXException, IOException {
    //Go to list page
    WebResponse response = this.conversation.getResource(organizationsRequest);
    //Go to view page
    WebTable listTable = response.getTableWithID(LIST_TABLE);
    String testName = listTable.getCellAsText(1, 0);
    WebRequest request = response.getLinkWith(testName).getRequest();
    response = this.conversation.getResource(request);
    //Go to delete page
    WebForm viewForm = response.getFormWithID(VIEW_FORM);
    request = viewForm.getRequest("delete");
    response = this.conversation.getResource(request);
    assertEquals("Checking page title", "Organizations List", response.getTitle());
    WebTable messageTable = response.getTableWithID(MESSAGE_TABLE);
    assertTrue("Checking table message", 
        messageTable.getCellAsText(0, 0).contains(testName));
    assertTrue("Checking table message", 
        messageTable.getCellAsText(0, 0).contains("successfully deleted"));
    //assertFalse("Checking " + testName + " is delete", this.myIsern.hasOrganization(testName));
  }

}
